package com.cicc.springboot.utile;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cicc.springboot.common.dto.R;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;

/**
 * 通用的Excel文件的导入导出监听器
 *
 * @ClassName GenericExcelListener
 * @Description 支持不同实体类的Excel导入
 * @Author 转轮王
 * @Date 2024/10/8 9:30
 * @Version 1.0
 */

public class GenericExcelListener<T> extends AnalysisEventListener<T> {

    private static final int BATCH_COUNT = 20;
    private List<T> list = new ArrayList<>();
    private final BaseMapper<T> mapper;
    private final StringBuilder responseMessage;
    private final Function<T, String> uniqueFieldExtractor; // 用于提取唯一字段（如物料号）
    private final Function<T, LambdaQueryWrapper<T>> queryWrapperFunction; // 用于自定义查询条件

    public GenericExcelListener(BaseMapper<T> mapper, Function<T, String> uniqueFieldExtractor, Function<T, LambdaQueryWrapper<T>> queryWrapperFunction) {
        this.mapper = mapper;
        this.responseMessage = new StringBuilder();
        this.uniqueFieldExtractor = uniqueFieldExtractor;
        this.queryWrapperFunction = queryWrapperFunction;
    }

    @Override
    public void invoke(T data, AnalysisContext context) {
        list.add(data);
        if (list.size() >= BATCH_COUNT) {
            saveData();
            list.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData();
    }

    private R<String> saveData() {
        List<T> validData = new ArrayList<>();
        Set<String> uniqueSet = new HashSet<>();

        // 遍历 Excel 数据，去除内部重复的唯一字段
        for (T data : list) {
            String uniqueField = uniqueFieldExtractor.apply(data);
            if (uniqueSet.add(uniqueField)) {
                validData.add(data);
            } else {
                responseMessage.append("Excel 中重复数据，保留一个，跳过: ").append(uniqueField).append(" ");
            }
        }

        List<T> finalDataToInsert = new ArrayList<>();

        // 与数据库中的数据进行比对，插入不存在的数据
        for (T data : validData) {
            LambdaQueryWrapper<T> queryWrapper = queryWrapperFunction.apply(data);

            if (mapper.selectCount(queryWrapper) == 0) {
                finalDataToInsert.add(data);
            } else {
                responseMessage.append("数据库中已存在，跳过: ").append(uniqueFieldExtractor.apply(data)).append(" ");
            }
        }

        // 将不重复且数据库中不存在的数据插入数据库
        if (!finalDataToInsert.isEmpty()) {
            for (T valid : finalDataToInsert) {
                mapper.insert(valid);
            }
            responseMessage.append("批量保存 ").append(finalDataToInsert.size()).append(" 条数据到数据库").append(" ");
        } else {
            responseMessage.append("无新的数据保存到数据库");
        }

        // 返回结果给前端
        return R.ok(responseMessage.toString());
    }

    // 新增一个方法用于获取响应消息
    public String getResponseMessage() {
        return responseMessage.toString();
    }
}
